#include "../terra-ge.h"
#include "inputlib.h"
#include "game.h"

using namespace TerraGE;

#define KEY_DELAY_TO_DOUBLEPRESS   22

#define MY_KEAYBOARD_SIZE          512

ALLEGRO_MOUSE_STATE mous;
ALLEGRO_KEYBOARD_STATE keyb;


char Keys_To_Check[512];
int Keyboard_Size=0;

char KB_Input[512];
char KB_Released[512];
char KB_DoublePressed[512];

char KB_Active[512];


float mouse_x, mouse_y, last_mouse_x, last_mouse_y, last_mouse_z, mouse_z, mick_x, mick_y, mick_z;

int Keyboard_Last_Pressed[512];
int KB_TimePressed[512];
int Keyboard_To_Double_Press[512];

void Init_Mapping() {
    int ind;

    ind = 0;
    while (ind != 512) {
        Keys_To_Check[ind] = 0;
        ++ind;
    }
    Keys_To_Check[ALLEGRO_KEY_A] = 1; Keys_To_Check[ALLEGRO_KEY_B] = 1;
    Keys_To_Check[ALLEGRO_KEY_C] = 1; Keys_To_Check[ALLEGRO_KEY_D] = 1;
    Keys_To_Check[ALLEGRO_KEY_E] = 1; Keys_To_Check[ALLEGRO_KEY_F] = 1;
    Keys_To_Check[ALLEGRO_KEY_G] = 1; Keys_To_Check[ALLEGRO_KEY_H] = 1;
    Keys_To_Check[ALLEGRO_KEY_I] = 1; Keys_To_Check[ALLEGRO_KEY_J] = 1;
    Keys_To_Check[ALLEGRO_KEY_K] = 1; Keys_To_Check[ALLEGRO_KEY_L] = 1;
    Keys_To_Check[ALLEGRO_KEY_M] = 1; Keys_To_Check[ALLEGRO_KEY_N] = 1;
    Keys_To_Check[ALLEGRO_KEY_O] = 1; Keys_To_Check[ALLEGRO_KEY_P] = 1;
    Keys_To_Check[ALLEGRO_KEY_Q] = 1; Keys_To_Check[ALLEGRO_KEY_R] = 1;
    Keys_To_Check[ALLEGRO_KEY_S] = 1; Keys_To_Check[ALLEGRO_KEY_T] = 1;
    Keys_To_Check[ALLEGRO_KEY_U] = 1; Keys_To_Check[ALLEGRO_KEY_V] = 1;
    Keys_To_Check[ALLEGRO_KEY_W] = 1; Keys_To_Check[ALLEGRO_KEY_X] = 1;
    Keys_To_Check[ALLEGRO_KEY_Y] = 1; Keys_To_Check[ALLEGRO_KEY_Z] = 1;
    Keys_To_Check[ALLEGRO_KEY_1] = 1; Keys_To_Check[ALLEGRO_KEY_2] = 1;
    Keys_To_Check[ALLEGRO_KEY_3] = 1; Keys_To_Check[ALLEGRO_KEY_4] = 1;
    Keys_To_Check[ALLEGRO_KEY_5] = 1; Keys_To_Check[ALLEGRO_KEY_6] = 1;
    Keys_To_Check[ALLEGRO_KEY_7] = 1; Keys_To_Check[ALLEGRO_KEY_8] = 1;
    Keys_To_Check[ALLEGRO_KEY_9] = 1; Keys_To_Check[ALLEGRO_KEY_0] = 1;
    Keys_To_Check[ALLEGRO_KEY_PAD_1] = 1; Keys_To_Check[ALLEGRO_KEY_PAD_2] = 1;
    Keys_To_Check[ALLEGRO_KEY_PAD_3] = 1; Keys_To_Check[ALLEGRO_KEY_PAD_4] = 1;
    Keys_To_Check[ALLEGRO_KEY_PAD_5] = 1; Keys_To_Check[ALLEGRO_KEY_PAD_6] = 1;
    Keys_To_Check[ALLEGRO_KEY_PAD_7] = 1; Keys_To_Check[ALLEGRO_KEY_PAD_8] = 1;
    Keys_To_Check[ALLEGRO_KEY_PAD_9] = 1; Keys_To_Check[ALLEGRO_KEY_PAD_0] = 1;
    Keys_To_Check[ALLEGRO_KEY_MOUSE_LCLICK] = 1;
    Keys_To_Check[ALLEGRO_KEY_MOUSE_RCLICK] = 1;
    Keys_To_Check[ALLEGRO_KEY_MOUSE_MCLICK] = 1;

    Keys_To_Check[ALLEGRO_KEY_ALT] = 1;
    Keys_To_Check[ALLEGRO_KEY_ESCAPE] = 1; Keys_To_Check[ALLEGRO_KEY_TILDE] = 1;
    Keys_To_Check[ALLEGRO_KEY_MINUS] = 1; Keys_To_Check[ALLEGRO_KEY_EQUALS] = 1;
    Keys_To_Check[ALLEGRO_KEY_BACKSPACE] = 1; Keys_To_Check[ALLEGRO_KEY_COMMA] = 1;
    Keys_To_Check[ALLEGRO_KEY_OPENBRACE] = 1; Keys_To_Check[ALLEGRO_KEY_TAB] = 1;
    Keys_To_Check[ALLEGRO_KEY_CLOSEBRACE] = 1; Keys_To_Check[ALLEGRO_KEY_ENTER] = 1;
    Keys_To_Check[ALLEGRO_KEY_QUOTE] = 1; Keys_To_Check[ALLEGRO_KEY_BACKSLASH] = 1;
    Keys_To_Check[ALLEGRO_KEY_FULLSTOP] = 1; Keys_To_Check[ALLEGRO_KEY_SLASH] = 1;
    Keys_To_Check[ALLEGRO_KEY_SEMICOLON] = 1; Keys_To_Check[ALLEGRO_KEY_BACKSLASH2] = 1;
    Keys_To_Check[ALLEGRO_KEY_SPACE] = 1; Keys_To_Check[ALLEGRO_KEY_DELETE] = 1;
    Keys_To_Check[ALLEGRO_KEY_INSERT] = 1; Keys_To_Check[ALLEGRO_KEY_END] = 1;
    Keys_To_Check[ALLEGRO_KEY_HOME] = 1; Keys_To_Check[ALLEGRO_KEY_PGUP] = 1;
    Keys_To_Check[ALLEGRO_KEY_PGDN] = 1; Keys_To_Check[ALLEGRO_KEY_LEFT] = 1;
    Keys_To_Check[ALLEGRO_KEY_RIGHT] = 1; Keys_To_Check[ALLEGRO_KEY_UP] = 1;
    Keys_To_Check[ALLEGRO_KEY_DOWN] = 1; Keys_To_Check[ALLEGRO_KEY_PAD_SLASH] = 1;
    Keys_To_Check[ALLEGRO_KEY_PAD_ASTERISK] = 1; Keys_To_Check[ALLEGRO_KEY_PAD_MINUS] = 1;
    Keys_To_Check[ALLEGRO_KEY_PAD_PLUS] = 1; Keys_To_Check[ALLEGRO_KEY_PAD_DELETE] = 1;
    Keys_To_Check[ALLEGRO_KEY_PAD_ENTER] = 1;
    Keys_To_Check[ALLEGRO_KEY_F1] = 1; Keys_To_Check[ALLEGRO_KEY_F6] = 1;
    Keys_To_Check[ALLEGRO_KEY_F2] = 1; Keys_To_Check[ALLEGRO_KEY_F7] = 1;
    Keys_To_Check[ALLEGRO_KEY_F3] = 1; Keys_To_Check[ALLEGRO_KEY_F8] = 1;
    Keys_To_Check[ALLEGRO_KEY_F4] = 1; Keys_To_Check[ALLEGRO_KEY_F9] = 1;
    Keys_To_Check[ALLEGRO_KEY_F5] = 1; Keys_To_Check[ALLEGRO_KEY_F10] = 1;
    Keys_To_Check[ALLEGRO_KEY_F11] = 1;Keys_To_Check[ALLEGRO_KEY_F12] = 1;
    Keys_To_Check[ALLEGRO_KEY_PRINTSCREEN]= 1;

    Keys_To_Check[ALLEGRO_KEY_LSHIFT] = 1;
    Keys_To_Check[ALLEGRO_KEY_LCTRL] = 1; Keys_To_Check[ALLEGRO_KEY_RCTRL] = 1;
}


 /*Clears all the buffers. Used for Transitions between Scenes*/
void Clear_Keyboard() {
  int ind, k;
  ind = 0;
  while (ind != 258) {
    if (Keys_To_Check[ind]) {
      k = ind;
      KB_TimePressed[k]=0;
      KB_DoublePressed[k]=0;
      Keyboard_To_Double_Press[k]=0;
      KB_Released[k]=0;
      KB_Input[k]=0;
      Keyboard_Last_Pressed[k]=0;
    }
    ++ind;
  }
}



void Poll_Input(void *instance) {
    Game *gInstance = (Game *) instance;

    int ind, k, joy_num, i;
    al_get_keyboard_state(&keyb);
    al_get_mouse_state(&mous);
    int mx, my;
    mx = mouse_x;
    my = mouse_y;

    last_mouse_x = mouse_x;
    last_mouse_y = mouse_y;
    last_mouse_z = mouse_z;

    mouse_x = al_get_mouse_state_axis(&mous, 0);
    mouse_y = al_get_mouse_state_axis(&mous, 1);
    mouse_z = mous.z;

    mick_x = mouse_x - mx;
    mick_y = mouse_y - my;
    mick_z = mouse_z - last_mouse_z;

    if (keyb.display != gInstance->Get_Display()) {
        Clear_Keyboard();
        return;
    }

    ind = 0;
    while (ind != 512) {
        if (Keys_To_Check[ind]) {
            k = ind;
            if (k < 256) {
                KB_Active[k]=0;
                KB_Input[k]=0;
                KB_Released[k]=0;
                KB_DoublePressed[k]=0;
                if (al_key_down(&keyb, k)) KB_Active[k]=1;
                if (Keyboard_To_Double_Press[k] > 0) Keyboard_To_Double_Press[k] -= 1;
                if (al_key_down(&keyb, k))  KB_TimePressed[k] += 1;
                else KB_TimePressed[k] = 0;
                if (KB_TimePressed[k] > 2000) KB_TimePressed[k] = 2000;
                if ((al_key_down(&keyb, k))  && (Keyboard_To_Double_Press[k] > 0)) {
                    KB_DoublePressed[k] = 1;
                    Keyboard_To_Double_Press[k] = 0;
                }
                if (!(al_key_down(&keyb, k)) && (Keyboard_Last_Pressed[k])) {
                    Keyboard_To_Double_Press[k] = KEY_DELAY_TO_DOUBLEPRESS;
                    KB_Released[k]=1;
                }
                if ((al_key_down(&keyb, k)) && (Keyboard_Last_Pressed[k] == 0)) {
                    KB_Input[k]=1;
                    Keyboard_Last_Pressed[k] = 1;
                }
                if (al_key_down(&keyb, k)) Keyboard_Last_Pressed[k] = 1;
                else Keyboard_Last_Pressed[k] = 0;
            }
            else if (k >= 256 && k <= 258) {
                if (k == ALLEGRO_KEY_MOUSE_LCLICK) i = al_mouse_button_down(&mous, 1);
                if (k == ALLEGRO_KEY_MOUSE_RCLICK) i = al_mouse_button_down(&mous, 2);
                if (k == ALLEGRO_KEY_MOUSE_MCLICK) i = al_mouse_button_down(&mous, 3);
                KB_Active[k]=0;
                if (i)KB_Active[k]=1;
                KB_Input[k]=0;
                KB_Released[k]=0;
                KB_DoublePressed[k]=0;
                if (Keyboard_To_Double_Press[k] > 0) Keyboard_To_Double_Press[k] -= 1;
                if (i) KB_TimePressed[k] += 1;
                else KB_TimePressed[k] = 0;
                if (KB_TimePressed[k] > 2000) KB_TimePressed[k] = 2000;
                if ((i) && (Keyboard_To_Double_Press[k] > 0)) {
                    KB_DoublePressed[k] = 1;
                    Keyboard_To_Double_Press[k] = 0;
                }
                if ((!i) && (Keyboard_Last_Pressed[k])) {
                    Keyboard_To_Double_Press[k] = KEY_DELAY_TO_DOUBLEPRESS;
                    KB_Released[k]=1;
                }
                if ((i) && (Keyboard_Last_Pressed[k] == 0)) {
                    KB_Input[k]=1;
                    Keyboard_Last_Pressed[k] = 1;
                }
                if (i) Keyboard_Last_Pressed[k] = 1;
                else Keyboard_Last_Pressed[k] = 0;
            }
        }
        ++ind;
    }
}
